﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace Perlin_Interactive_Demo_1
{
    static class CellProcedural
    {
        static bool isInitalized = false;
        const int UNIT_GRIDS = 3;
        const int CELL_COUNT = 6;
        static Vector3[] basedata = new Vector3[CELL_COUNT];

        public static void Generate(ref Texture2D texture, float phase)
        {
            if (!isInitalized)
                InitalizeNoise();

            Color[] buffer = new Color[texture.Width * texture.Height];
            float pixel = 0f;

            for (int x = 0; x < texture.Width; x++)
            {
                float xCoord = (float)x / (float)texture.Width;

                for (int y = 0; y < texture.Height; y++)
                {
                    float yCoord = (float)y / (float)texture.Height;

                    pixel = Cells(xCoord, yCoord, phase);
                    pixel = Math.Min(1f, Math.Max(0f, pixel));
                    buffer[x + (y * texture.Width)] = new Color(pixel, pixel, pixel);
                }
            }

            texture.SetData<Color>(buffer);
        }

        static Vector3 QueryBase(int x)
        {
            return basedata[(x % CELL_COUNT)];
        }

        static void InitalizeNoise()
        {
            for (int x = 0; x < CELL_COUNT; x++)
            {
                //basedata[x] = Vector3.Zero;// new Vector3(Util.RandomFloat(0f, 1f), Util.RandomFloat(0f, 1f), Util.RandomFloat(0f, 1f));
                float zCluster = Util.RandomFloat(0.25f, 0.75f);
                basedata[x] = new Vector3(Util.RandomFloat(0f, 1f), Util.RandomFloat(0f, 1f), zCluster);
            }

            isInitalized = true;
        }

        static float Cells(float xCoord, float yCoord, float zCoord)
        {
            float x = xCoord - (float)Math.Floor(xCoord);
            float y = yCoord - (float)Math.Floor(yCoord);
            float z = zCoord - (float)Math.Floor(zCoord);
            float total = 0f;

            Vector3 coordPosition = new Vector3(x, y, z);

            float minFirst = float.MaxValue;
            float minSecond = float.MaxValue;

            int firstClosest = -1;
            int secondClosest = -1;

            for (int i = 0; i < CELL_COUNT; i++)
            {
                Vector3 cellPosition = QueryBase(i);
                float dist = Vector3.Distance(coordPosition, cellPosition);

                if (dist < minSecond)
                {
                    if (dist < minFirst)
                    {
                        minSecond = minFirst;
                        secondClosest = firstClosest;

                        minFirst = dist;
                        firstClosest = i;
                    }
                    else
                    {
                        minSecond = dist;
                        secondClosest = i;
                    }
                }
            }

            int invScale = 15;

            total = (1f / MathHelper.Clamp(minFirst * minFirst * invScale,0,1)) 
                    //+ (1f / (minSecond * minSecond * invScale))
                    + 0;
            total *= .25f;
            return total;
        }

        //static float Cells(float xCoord, float yCoord, float zCoord)
        //{
        //    float x = xCoord - (float)Math.Floor(xCoord);
        //    float y = yCoord - (float)Math.Floor(yCoord);
        //    float z = zCoord - (float)Math.Floor(zCoord);
        //    float total = 0f;

        //    Vector3 coordPosition = new Vector3(x, y, z);

        //    for (int i = 0; i < CELL_COUNT; i++)
        //    {
        //        Vector3 cellPosition = QueryBase(i);
        //        float inc = 0f;

        //        float dist = Vector3.Distance(coordPosition, cellPosition) * 5;
        //        inc = 1f / (dist * dist);
        //        inc = MathHelper.Clamp(inc, 0f, 1f);
        //        //float dist = Vector3.Distance(coordPosition, cellPosition);
        //        //inc = 1f - MathHelper.Clamp(dist, 0f, 1f);


        //        total += inc;
        //    }
        //    total /= CELL_COUNT;
        //    return total;
        //}
    }
}
